#
#   Copyright 2010 Matthew Crinklaw-Vogt
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#  limitations under the License.
#

import urllib2
import urllib
import gzip
import StringIO
import json

def convertDate(pDate):
    return 0

# TODO: do some auto-date conversion?
# TODO: make this smarter
# / able to handle errors and non-gzipped responses and so on.
class PyXchange:
    # TODO: is there a notion of static members in python?
    _allowableParametes = set()
    _paramsThatRequireConversion = {
                                    'fromdate': convertDate,
                                    'todate': convertDate 
                                    }
    
    def __init__(self, pStackExchangeSite):
        self.stackExchangeSite = pStackExchangeSite
        self.parameters = {}
        self.urlPostfix = ''
        allowableParams = [
                           'body',
                           'comments',
                           'answers',
                           'fromdate',
                           'max',
                           'min',
                           'order',
                           'page',
                           'pagesize',
                           'sort',
                           'todate',
                           'tagged',
                           'nottagged',
                           'filter',
                           'key'
                           ]
        self._allowableParametes |= set(allowableParams)
    
    def __getattr__(self, attr):
        def default_method(*args):
            self.apply(attr, *args)
            return self
        return default_method
    
    def apply(self, *args):
        if args[0] == 'answers' and type(args[1]) == type(0):
            self._handlePath(args)
        elif args[0] in self._allowableParametes:
            self._handleParam(args)
        else:
            self._handlePath(args)
    
    def _handleParam(self, *args):
        self.parameters[args[0][0]] = self._convertParameter(args[0][0], args[0][1])
    
    def _convertParameter(self, pParamName, pParamValue):
        if pParamName in self._paramsThatRequireConversion:
            return self._paramsThatRequireConversion[pParamName](pParamValue)
        return pParamValue
    
    def _handlePath(self, *args):
        argList = list(args[0])
        self.__handlePath(argList)
    
    def __handlePath(self, argList):
        self.urlPostfix += '/'
        self.urlPostfix += argList[0].__str__()
        
        if len(argList) > 1:
            argList.pop(0)
            self.__handlePath(argList)
    
    def execute(self):
        params = urllib.urlencode(self.parameters)
        apiRequest = self.stackExchangeSite + self.urlPostfix
        if len(self.parameters) > 0:
            apiRequest += '?' + params
        httpRequest = urllib2.Request(apiRequest)
        
        httpRequest.add_header('Accept-Encoding', 'gzip')
        # give em some randy user agent
        httpRequest.add_header('Referer', 'http://www.tantaman.com/stack-trac')
        opener = urllib2.build_opener()
        response = opener.open(httpRequest)
        
        if response.headers.get('Content-Encoding') == 'gzip':
            compressedData = response.read()
            compressedStream = StringIO.StringIO(compressedData)
            gzippper = gzip.GzipFile(fileobj=compressedStream)
            uncompressedResponse = gzippper.read()
        else:
            uncompressedResponse = response.read()
        
        return json.loads(uncompressedResponse)

#obj = PyXchange('api.stackoverflow.com/1.0')
#print obj.search().tagged('java').execute()

